<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>Class: Array</title>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
  <script type="text/javascript">
  // <![CDATA[

  function popupCode( url ) {
    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
  }

  function toggleCode( id ) {
    if ( document.getElementById )
      elem = document.getElementById( id );
    else if ( document.all )
      elem = eval( "document.all." + id );
    else
      return false;

    elemStyle = elem.style;
    
    if ( elemStyle.display != "block" ) {
      elemStyle.display = "block"
    } else {
      elemStyle.display = "none"
    }

    return true;
  }
  
  // Make codeblocks hidden by default
  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
  
  // ]]>
  </script>

</head>
<body>



    <div id="classHeader">
        <table class="header-table">
        <tr class="top-aligned-row">
          <td><strong>Class</strong></td>
          <td class="class-name-in-header">Array</td>
        </tr>
        <tr class="top-aligned-row">
            <td><strong>In:</strong></td>
            <td>
                <a href="../files/enhanced_arg_parser_rb.html">
                enhanced_arg_parser.rb
                </a>
        <br />
            </td>
        </tr>

        <tr class="top-aligned-row">
            <td><strong>Parent:</strong></td>
            <td>
                Object
            </td>
        </tr>
        </table>
    </div>
  <!-- banner header -->

  <div id="bodyContent">



  <div id="contextContent">

    <div id="description">
      <p>
enhanced arg parser for ruby
</p>

    </div>


   </div>

    <div id="method-list">
      <h3 class="section-bar">Methods</h3>

      <div class="name-list">
      <a href="#M000001">args</a>&nbsp;&nbsp;
      </div>
    </div>

  </div>


    <!-- if includes -->

    <div id="section">





      


    <!-- if method_list -->
    <div id="methods">
      <h3 class="section-bar">Public Instance methods</h3>

      <div id="method-M000001" class="method-detail">
        <a name="M000001"></a>

        <div class="method-heading">
          <a href="Array.src/M000001.html" target="Code" class="method-signature"
            onclick="popupCode('Array.src/M000001.html');return false;">
          <span class="method-name">args</span><span class="method-args">(*settings_array)</span>
          </a>
        </div>
      
        <div class="method-description">
          <p>
This function adds to ruby the ability to parse method parameters as if
they were named.
</p>
<p>
Benefits: named parameters are cleaner to use, decrease the number of bugs.
They can also be entered in arbitrary order, so less hassle going back to
figure out exactly which order was which. They can also be passed as a
hash, and so re-used from call to call. It is a drop in replacement for
existing Ruby, allowing for both required and optional arguments.
</p>
<p>
Basically, they make a cleaner, slicker, easier to read and use Ruby.
</p>
<p>
drawback: small performance hit, auto-complete might not work as well on
some IDE&#8216;s [like we use that anyway], and you have to type the
variable name in twice
</p>
<pre>
 doctest: basic syntax
 &gt;&gt; def method1 *as
       required1, required2 = as.args [:required1, :required2] # pass required arguments as an array of names
       end
 You can the call functions with or without named parameters, a la
  &gt;&gt; method1 1, 2
  =&gt; [1, 2]
  &gt;&gt; method1 :required1 =&gt; 1, :required2 =&gt; 2
  =&gt; [1, 2]
</pre>
<p>
It allows for optional parameters as well
</p>
<pre>
 &gt;&gt; def method2 *as
     required1, required2, optional1, optional2 = as.args [:required1, :required2], {:optional1 =&gt; 3}, {:optional2 =&gt; 4}
     [required1, required2, optional1, optional2]
     end
 and use it:
 &gt;&gt; method2 1, 2, :optional2 =&gt; 5
 =&gt; [1, 2, 3, 5]
 &gt;&gt; method2 33, 44
 =&gt; [33, 44, 3, 4]
</pre>
<p>
You don&#8216;t have to use names [works with existing Ruby syntax]
</p>
<pre>
 &gt;&gt; method2 33, 44, 55, 66
 =&gt; [33, 44, 55, 66]
</pre>
<p>
But can use all names if desired for clarity
</p>
<pre>
 &gt;&gt; method2 :required1 =&gt; 33, :required2 =&gt; 44, :optional1 =&gt; 55, :optional2 =&gt; 66
 =&gt; [33, 44, 55, 66]
</pre>
<p>
you can mix the order, just note that once you start naming parameters, you
can only use named parameters
</p>
<pre>
 &gt;&gt; method2 :optional1 =&gt; 33, :required2 =&gt; 44, :optional2 =&gt; 55, :required1 =&gt; 66
 =&gt; [66, 44, 33, 55]
</pre>
<p>
and you can start with non-named and then use named
</p>
<pre>
 &gt;&gt; method2 11, :required2 =&gt; 33, :optional2 =&gt; 77
 =&gt; [11, 33, 3, 77]
</pre>
<p>
note that you can also use and re-use hashes as parameters
</p>
<pre>
 &gt;&gt; opts = {:required1 =&gt; 11, :required2 =&gt; 22}
 &gt;&gt; method2 opts
 =&gt; [11, 22, 3, 4]
</pre>
<p>
now re-use parameters
</p>
<pre>
 &gt;&gt; method2 opts
 =&gt; [11, 22, 3, 4]
</pre>
<p>
compatible as a drop in replacement for existing methods:
</p>
<pre>
 def method3 a, b, c, d = 4
</pre>
<p>
&#8230; becomes [without changing the way it is called anywhere]
</p>
<pre>
 &gt;&gt; def method3 *as
     a, b, c, d = as.args [:a, :b, :c], {:d =&gt; 4}
     end
 &gt;&gt; method3 1, 2, 3
 =&gt; [1, 2, 3, 4]
</pre>
<p>
advanced use: it can also replace existing params &quot;partially&quot;
&#8212; say you want to be able to pass you last 2 parameters with names,
of an existing function
</p>
<pre>
 def method5 a, b, c, d
</pre>
<p>
becomes
</p>
<pre>
 &gt;&gt; def method5 a, b, *as
     c, d = as.args [:c, :d]
     [a, b, c, d]
     end

 &gt;&gt; method5 1, 2, :c =&gt; 3, :d =&gt; 4
 =&gt; [1, 2, 3, 4]
</pre>
<p>
what if you used to use a hash as your last parameter? (You still can, you
just have to change it to pass a named parameter for the ending hash)
</p>
<pre>
 doctest: example with a last hash
 &gt;&gt; def uses_ending_hash *as
     param1, options = as.args [:param1], {:options =&gt; {}}
     end

 &gt;&gt; uses_ending_hash 3
 =&gt; [3, {}]
 &gt;&gt; uses_ending_hash 3, :options =&gt; {:be_aggressive =&gt; true}
 =&gt; [3, {:be_aggressive =&gt; true}]
 &gt;&gt; uses_ending_hash 3, :options =&gt; {:be_aggressive =&gt; true, :force =&gt; true}
 =&gt; [3, {:be_aggressive =&gt; true, :force =&gt; true}]
 doctest: NOTE in some rare cases you have to monkey a little bit--if your default values cause side effects, it's overcomeable
</pre>
<p>
old style was: def method4 a, b = a * some_method_with_side_effects #
some_method_with_side_effects isn&#8216;t run, normally, if you pass a
value for b new style: we&#8216;ll accomplish essentially the same thing
using ||=
</p>
<pre>
 &gt;&gt; $count = 0
</pre>
<p>
count should increase only if we don&#8216;t pass anything to b
</p>
<pre>
 &gt;&gt; def method4 *as
     a, b = as.args [:a], {:b =&gt; nil}
     b ||= ($count += 1)
     $count
     end

 &gt;&gt; method4 1, 2 # shouldn't increment
 &gt;&gt; 0
 &gt;&gt; method4 1 # should increment
 &gt;&gt; 1
 &gt;&gt; method4 :a =&gt; 2 # should increment
 =&gt; 2
 &gt;&gt; method4 :a =&gt; 1, :b =&gt; 2 # should not increment
 =&gt; 2 # didn't increment
</pre>
<p>
see also the file enhanced_arg_parser.doctest.rb for more examples.
</p>
<p>
future work: ltodo optimize for speed &#8212; some of these run-time checks
may not be necessary, especially except in development :)
</p>
<p>
ltodo: move into C if possible :)
</p>
<p>
ltodo: verify against classes, too, like dynamic type checking, only if the
user desires.
</p>
        </div>
      </div>


    </div>


  </div>


<div id="validator-badges">
  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
</div>

</body>
</html>